<?php

namespace MyLogger;

class Logger
{
    // 日志级别常量
    const DEBUG = 100;
    const INFO = 200;
    const NOTICE = 250;
    const WARNING = 300;
    const ERROR = 400;
    const CRITICAL = 500;
    const ALERT = 550;
    const EMERGENCY = 600;

    // 级别名称映射
    protected static $levels = [
        self::DEBUG => 'DEBUG',
        self::INFO => 'INFO',
        self::NOTICE => 'NOTICE',
        self::WARNING => 'WARNING',
        self::ERROR => 'ERROR',
        self::CRITICAL => 'CRITICAL',
        self::ALERT => 'ALERT',
        self::EMERGENCY => 'EMERGENCY',
    ];

    protected $name;       // 日志器名称
    protected $handlers;   // 处理器数组
    protected $timezone;   // 时区
    protected $processors = []; // 日志处理器

    public function __construct(string $name, array $handlers = [], \DateTimeZone $timezone = null)
    {
        $this->name = $name;
        $this->handlers = $handlers;
        $this->timezone = $timezone ?: new \DateTimeZone(date_default_timezone_get() ?: 'UTC');
    }

    public function addHandler(Handlers\HandlerInterface $handler)
    {
        $this->handlers[] = $handler;
    }

    public function pushProcessor(callable $callback)
    {
        array_unshift($this->processors, $callback);
    }

    // 核心记录方法
    public function log($level, string $message, array $context = [])
    {
        if (!is_int($level) || !isset(self::$levels[$level])) {
            throw new \InvalidArgumentException('Unknown log level');
        }

        $record = [
            'message' => $message,
            'context' => $context,
            'level' => $level,
            'level_name' => self::getLevelName($level),
            'channel' => $this->name,
            'datetime' => new \DateTimeImmutable('now', $this->timezone),
            'extra' => [],
        ];

        // 处理日志记录
        foreach ($this->processors as $processor) {
            $record = $processor($record);
        }

        // 传递给所有处理器
        foreach ($this->handlers as $handler) {
            $handler->handle($record);
        }
    }

    // 快速记录方法
    public function debug($message, array $context = []) {
        $this->log(self::DEBUG, $message, $context);
    }

    public function info($message, array $context = []) {
        $this->log(self::INFO, $message, $context);
    }

    public function notice($message, array $context = []) {
        $this->log(self::NOTICE, $message, $context);
    }

    public function warning($message, array $context = []) {
        $this->log(self::WARNING, $message, $context);
    }

    public function error($message, array $context = []) {
        $this->log(self::ERROR, $message, $context);
    }

    public function critical($message, array $context = []) {
        $this->log(self::CRITICAL, $message, $context);
    }

    public function alert($message, array $context = []) {
        $this->log(self::ALERT, $message, $context);
    }

    public function emergency($message, array $context = []) {
        $this->log(self::EMERGENCY, $message, $context);
    }

    // 静态方法
    public static function getLevelName($level)
    {
        return self::$levels[$level] ?? 'UNKNOWN';
    }
}